#include "mainwindow.h"
#include "ui_mainwindow.h"

#define VALUE_DIS 5

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow) {
    ui->setupUi(this);
	InitElem();          // 初始化
    SetWindow();         // 窗体设置
    LoadModules();       // 加载模块 

    // 管理员按钮点击显示或隐藏状态信息
    /*ui->m_right->setCurrentIndex(1);

    connect(ui->right_manager,&QToolButton::clicked,this,[&](){
        if(btn5 == 0)
        {
            connect(ui->right_manager,&QToolButton::clicked,[&](){
                ui->m_right->setCurrentIndex(btn5);
            });
            btn5 = 1;
        }
        else
        {
            connect(ui->right_manager,&QPushButton::clicked,[&](){
                ui->m_right->setCurrentIndex(btn5);
            });
            btn5 = 0;
        }
    });


    // 创建socket
    udpSocket = new QUdpSocket(this);
    //组播的绑定
    udpSocket->bind(QHostAddress::AnyIPv4, xxxx);    //QUdpSocket::ShareAddress
    // 加入组播
    udpSocket->joinMulticastGroup(QHostAddress("xxx.xxx.xxx.xxx"));

    connect(udpSocket, &QUdpSocket::readyRead, this, &MainWindow::dealMsg);
    // 每秒发送计时信号，各个报文消息生存时间减少
    startTimer(1000);*/
}

MainWindow::~MainWindow() {
    delete m_manager;
    delete m_addbutton;
    delete ui;
}

void MainWindow::InitElem() {
    m_manager = new ModulesManager();
    m_addbutton = nullptr;

    // Add 按钮
    m_addbutton = new ModuleBtn(ui->home);
    QIcon* add_icon = new QIcon;
    add_icon->addFile(":/add.png");
    m_addbutton->SetModuleIcon(add_icon);
    m_addbutton->SetModuleText("添加模块");
    m_addbutton->show();

    connect(m_addbutton, &ModuleBtn::sendRefresh, this, [=]() {
        m_vme = m_manager->AddModules();
        ShowModules();
    });

    // 样式赋值
    btnStyleHover =
            "QPushButton{ \
                font-family:'方正黑体'; \
                font-size:16px; \
                color:rgb(142,164,187); \
                border:10px; \
                border-radius:20px; \
                padding:10px 10px; \
            } \
            QPushButton:hover{ \
                color: rgb(209,219,231); \
                background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(22,56,98), stop:0.3 rgb(22,56,98), stop:1 rgb(22,56,98)); \
                border:10px; \
                border-radius:20px; \
                padding:10px 10px; \
            }";

   btnStyleClicked =
            "QPushButton{ \
                font-family:'方正黑体'; \
                font-size:16px; \
                color:rgb(220,220,231); \
                border:10px; \
                border-radius:20px; \
                padding:10px 10px; \
                background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(22,56,98), stop:0.3 rgb(22,56,98), stop:1 rgb(22,56,98)); \
            }";
}

void MainWindow::SetWindow() {
    this->setWindowFlags(Qt::CustomizeWindowHint);
    // 设置窗口名称
    this->setWindowTitle("外部环境模拟器");
    // 设置窗口最大化
    QDesktopWidget* desktop = QApplication::desktop();
    this->resize(desktop->width(), desktop->height());
    // 设置 LOGO
    QIcon icon_app;
    icon_app.addFile(":/logo.png");
    this->setWindowIcon(icon_app);
    ui->title->setStyleSheet("color:white");
    // 设置最小化按钮图标
    QIcon icon_min;
    icon_min.addFile(":/minimize.png");
    ui->min->setFlat(true);
    ui->min->setIconSize(QSize(35, 35));
    ui->min->setIcon(icon_min);
    // 设置关闭按钮图标
    QIcon icon_close;
    icon_close.addFile(":/mainclose.png");
    ui->close->setFlat(true);
    ui->close->setIconSize(QSize(35, 35));
    ui->close->setIcon(icon_close);
    // 首页设置
    ui->home->resize(desktop->width(), desktop->height());
    // 设置首页背景图
    ui->background->resize(desktop->width(), desktop->height());
    ui->background->setPixmap(QPixmap(":/background.png"));
    ui->background->setScaledContents(true);
    // main页设置
    ui->main->resize(desktop->width() + 15, desktop->height());
    ui->top->resize(QSize(desktop->width() + 15, 80));
    ui->top->setPixmap(QPixmap(":/top.png"));
    ui->top->setScaledContents(true);
    // right页设置
    ui->right->move(desktop->width() - 560 + 10, 80);
    ui->right->resize(QSize(560, desktop->height() - 80));
    ui->right_bg->resize(QSize(560, desktop->height() - 80));
    ui->right_bg->resize(560, desktop->height() - 80);
    ui->right_bg->setPixmap(QPixmap(":/right.png"));
    ui->right_bg->setScaledContents(true);
    QIcon icon_right_manager;
    icon_right_manager.addFile(":/shrink.png");
    ui->right_manager->setIconSize(QSize(35, 35));
    ui->right_manager->setIcon(icon_right_manager);
    ui->right_manager->setFlat(true);

    ui->right_id->setStyleSheet("background-color:#2599eb");
}

void MainWindow::LoadModules() {
    m_vme = m_manager->LoadModule();
    ShowModules();
}

void MainWindow::ShowModules() {
    // 添加Widget
    for(int i = 0; i < m_vme.size(); ++i) {
        m_vme.at(i)->topbtn->setStyleSheet(btnStyleHover);

        m_vme.at(i)->mobtn->setParent(ui->home);
        m_vme.at(i)->topbtn->setParent(ui->main);
        m_vme.at(i)->widget->setParent(ui->main);

        m_vme.at(i)->widget->move(0, 80);
        m_vme.at(i)->topbtn->move(400 + i * 200, 20);
        m_vme.at(i)->topbtn->show();
    }

    for(int i = 0; i < m_vme.size(); ++i) {
        disconnect(m_vme.at(i)->topbtn, &QPushButton::clicked, this, 0);
        connect(m_vme.at(i)->topbtn, &QPushButton::clicked, this, [=]() {
            for(int j = 0; j < m_vme.size(); ++j) {
                m_vme.at(j)->topbtn->setStyleSheet(btnStyleHover);
                m_vme.at(j)->widget->hide();
                if(i == j) {
                    m_nowIndex = i;
                    m_vme.at(j)->topbtn->setStyleSheet(btnStyleClicked);
                    if(rightIsOpen) {
                        m_vme.at(j)->widget->resize(2015, 1520);
                    }
                    else {
                        m_vme.at(j)->widget->resize(2570, 1520);
                    }
                    m_vme.at(j)->widget->show();
                }
            }
        });
    }

    // 导航页显示
    int i = 0;
    for(; i < m_vme.size(); ++i) {
        m_vme.at(i)->mobtn->SetModuleIndex(i, false);

        disconnect(m_vme.at(i)->mobtn, &ModuleBtn::sendModuleIndex, this, 0);
        disconnect(m_vme.at(i)->mobtn, &ModuleBtn::sendCloseIndex, this, 0);

        connect(m_vme.at(i)->mobtn, &ModuleBtn::sendCloseIndex, this, [=](const int& index) {
            m_vme = m_manager->DelModule(index);
            ShowModules();
        });

        connect(m_vme.at(i)->mobtn, &ModuleBtn::sendModuleIndex, this, [=](const int& index) {
            m_vme.at(index)->topbtn->clicked();
            ui->home->hide();
            ui->main->show();
            ui->right_manager->show();

        });

        m_vme.at(i)->mobtn->move((80 + (i % 5) * 500), 100 + ((i / 5) * 500));
        m_vme.at(i)->mobtn->show();
    }

    m_addbutton->SetModuleIndex(i, true);
    m_addbutton->move((80 + (i % 5) * 500), 100 + ((i / 5) * 500));
}

void MainWindow::on_min_clicked() {
    this->showMinimized();
}

void MainWindow::on_close_clicked() {
    this->close();
}

void MainWindow::on_homebtn_clicked() {
    ui->home->show();
    ui->main->hide();
    ui->right_manager->hide();
}

void MainWindow::on_right_manager_clicked() {
    if(rightIsOpen) {
        QIcon icon_right_manager;
        icon_right_manager.addFile(":/shrink.png");
        ui->right_manager->setIconSize(QSize(35, 35));
        ui->right_manager->setIcon(icon_right_manager);
        QString pressStyle =
                "QPushButton:pressed{ border: 60px; }";
        ui->right_manager->setStyleSheet(pressStyle);
        ui->right->hide();
        m_vme.at(m_nowIndex)->widget->resize(2570, 1520);
        rightIsOpen = false;
    }
    else {
        QIcon icon_right_manager;
        icon_right_manager.addFile(":/open.png");
        ui->right_manager->setIconSize(QSize(35, 35));
        ui->right_manager->setIcon(icon_right_manager);
        QString pressStyle =
                "QPushButton:pressed{ border: 60px; }";
        ui->right_manager->setStyleSheet(pressStyle);
        ui->right->show();
        m_vme.at(m_nowIndex)->widget->resize(2015, 1520);
        rightIsOpen = true;
    }
    ui->centralWidget->update();
}

QString MainWindow::GetMyIP() {
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    foreach (QHostAddress address, list) {
        if(address.protocol() == QAbstractSocket::IPv4Protocol) {
            cout << address.toString();
            return address.toString();
        }
    }
    return 0;
}

// 每秒处理，超过5s删除报文以及tree中数据
void MainWindow::timerEvent(QTimerEvent *event)
{
    //当前报文和他的剩余生存时间
    QHash<QString,int>::iterator nowtime;
    for( nowtime=m_time.begin(); nowtime!=m_time.end(); ++nowtime)
    {
        nowtime.value()--;
        if(nowtime.value() == 0) //如果生存时间为0，则清除本条报文
        {
            int index = hadState.indexOf(nowtime.key());
            QStringList delmod = nowtime.key().split("#");

            //用 it 遍历treewidget
            QTreeWidgetItemIterator it(ui->treeWidget);
            while (*it)
            {
                if(delmod[0] == (*it)->text(0) ) //如果此时报文ip和当前指向的节点一样
                {
                    if(  (*it)->childCount() == 0 || (*it)->childCount() == 1 ) //剩余一个和0个子节点都要清除整个ip
                    {
                        int con = 0;
                        for(int n=0;n<ui->treeWidget->topLevelItemCount();n++)
                        {
                            if((*it) == ui->treeWidget->topLevelItem(n))
                            {
                                con = n;
                            }
                        }
                        ui->treeWidget->takeTopLevelItem(con);
                        hadState.remove(index);
                        m_time.remove(nowtime.key());
                        return;
                    }
                    else // 剩余多个子节点时只需删除一个
                    {
                        for(int modindex = 0; modindex < (*it)->childCount() ;modindex++)
                        {
                            if(delmod[1] == (*it)->child(modindex)->text(0) )
                            {
                                (*it)->removeChild((*it)->child(modindex));
                                hadState.remove(index);
                                m_time.remove(nowtime.key());
                                return;
                            }
                        }
                    }
                }
                ++it;
            }

            hadState.remove(index);
            m_time.remove(nowtime.key());
        }
    }
}

// 接受模块发来的状态消息，添加到tree中
void MainWindow::dealMsg()
{
    QByteArray ba;
    ui->treeWidget->setHeaderLabels(QStringList() << "方法名称" << " "<< " "<< "状态");
    //设置状态栏间隔
    ui->treeWidget->setColumnWidth(0, 175);
    ui->treeWidget->setColumnWidth(1, 50);
    ui->treeWidget->setColumnWidth(2, 50);
    ui->treeWidget->setColumnWidth(3, 125);
    //默认展开
//    ui->treeWidget->expandAll();

    while(udpSocket->hasPendingDatagrams())
    {

        ba.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(ba.data(), ba.size());
        QString itinfo = ba.data();
        cout << "接收了：" <<  itinfo;
        QStringList iteminfolist = itinfo.split("#");
        if(hadState.indexOf(itinfo) >= 0 )// 存在相同直接退出
        {
            m_time[itinfo] = 5;//生存时间重置
            return;
        }
        else//信息存在不同，分为ip不同，模块名不同，函数名不同
        {
            for(int i=0; i<hadState.count(); ++i)//判断ip是否存在相同
            {
                QStringList hadstateip = hadState[i].split("#");
                if(hadstateip[0] == iteminfolist[0])
                    ipsame = i;
                else
                    ipsame = -1;
            }

            if(ipsame >= 0)//ip相同
            {
                for(int i=0;i<hadState.count();i++)//判断ip是否存在相同
                {
                    QStringList olditem = hadState[i].split("#");
                    if(olditem[1] == iteminfolist[1])
                        ips = i;
                    else
                        ips = -1;
                }

                if(ips >= 0 )//模块名相同，证明功能不同，更新功能列表
                {
                    ui->treeWidget->clear();
                    hadState.remove(ips);
                    return;
                }
                else //模块名不同，新添加模块
                {
                    cout << "添加新模块";
                    //添加模块、功能、功能所携带的按钮
                    QTreeWidgetItemIterator it(ui->treeWidget);
                    while (*it)
                    {
                        QString h = QString(iteminfolist[0]);
                        if((*it)->text(0) == h )
                        {
                            QTreeWidgetItem* mod = new QTreeWidgetItem(QStringList(iteminfolist[1]));
                            QTreeWidgetItem *nowipitem = *it;
                            nowipitem->addChild(mod);
                            for(int i = 1; i < iteminfolist[2].toInt()+1; ++i)
                            {
                                QTreeWidgetItem* funandState = new QTreeWidgetItem(QStringList(iteminfolist[i + 2]));
                                mod->addChild(funandState);

                                QPushButton *topLevelButton = new QPushButton(" 开启 ");
                                topLevelButton->resize(5,10);
                                QPushButton *topLevelButton2 = new QPushButton(" 关闭 ");
                                topLevelButton2->resize(5,5);

                                //设置 Item 内控件，0 是第几列
                                ui->treeWidget->setItemWidget(funandState, 1, topLevelButton);
                                ui->treeWidget->setItemWidget(funandState, 2, topLevelButton2);
                                //开启
                                connect(topLevelButton,&QPushButton::clicked,this,[=](){

                                    QPushButton *sendObj = qobject_cast<QPushButton*>(sender());
                                    QTreeWidgetItem *item = ui->treeWidget->itemAt(QPoint(sendObj->frameGeometry().x(),sendObj->frameGeometry().y()));

                                    QString nowip = item->parent()->parent()->text(0);

                                    QString nowfuncmes = item->text(0);

                                    MainWindow::sendfunc(nowip,"2000",nowfuncmes+"#1");
                                });
                                //关闭
                                connect(topLevelButton2,&QPushButton::clicked,this,[=](){

                                    QPushButton *sendObj = qobject_cast<QPushButton*>(sender());
                                    QTreeWidgetItem *item = ui->treeWidget->itemAt(QPoint(sendObj->frameGeometry().x(),sendObj->frameGeometry().y()));

                                    QString nowip = item->parent()->parent()->text(0);

                                    QString nowfuncmes = item->text(0);

                                    MainWindow::sendfunc(nowip,"2000",nowfuncmes+"#0");
                                });
                            }
                            hadState << itinfo;
                            m_time.insert(itinfo,5);
                            return;
                        }
                        ++it;
                    }
                    return;
                }
            }

            hadState << itinfo;
            m_time.insert(itinfo,5);
        }
        //添加一整个ip、模块、功能；
        QTreeWidgetItem* ip = new QTreeWidgetItem(QStringList(iteminfolist[0]));
        ui->treeWidget->addTopLevelItem(ip);

        QTreeWidgetItem* modl = new QTreeWidgetItem(QStringList(iteminfolist[1]));
        ip->addChild(modl);
        for(int i = 1; i < iteminfolist[2].toInt()+1; ++i)
        {
            QTreeWidgetItem* funandState = new QTreeWidgetItem(QStringList(iteminfolist[i + 2]));
            modl->addChild(funandState);
            QPushButton *topLevelButton = new QPushButton(" 开启 ");
            topLevelButton->resize(5,10);
            QPushButton *topLevelButton2 = new QPushButton(" 关闭 ");
            topLevelButton2->resize(5,5);
            //设置 Item 内控件，0 是第几列
            ui->treeWidget->setItemWidget(funandState, 1, topLevelButton);
            ui->treeWidget->setItemWidget(funandState, 2, topLevelButton2);
            //开启
            connect(topLevelButton,&QPushButton::clicked,this,[=](){
                QPushButton *sendObj = qobject_cast<QPushButton*>(sender());
                QTreeWidgetItem *item = ui->treeWidget->itemAt(QPoint(sendObj->frameGeometry().x(),sendObj->frameGeometry().y()));
                QString nowip = item->parent()->parent()->text(0);
                QString nowfuncmes = item->text(0);
                MainWindow::sendfunc(nowip,"2000",nowfuncmes+"#1");
            });
            //关闭
            connect(topLevelButton2,&QPushButton::clicked,this,[=](){
                QPushButton *sendObj = qobject_cast<QPushButton*>(sender());
                QTreeWidgetItem *item = ui->treeWidget->itemAt(QPoint(sendObj->frameGeometry().x(),sendObj->frameGeometry().y()));
                QString nowip = item->parent()->parent()->text(0);
                QString nowfuncmes = item->text(0);
                MainWindow::sendfunc(nowip,"2000",nowfuncmes+"#0");
            });
        }
    }
}

// 发送函数到对应的ip去，目标模块回调功能；
void MainWindow::sendfunc(QString ip, QString port, QString content)
{
    QUdpSocket qus;
    ip = "224.0.0.2";    //这里的ip还有问题
    qus.writeDatagram(content.toUtf8(), QHostAddress(ip), port.toShort());
    cout << "成功" << content ;
}
